package com.ruicar.afs.cloud.afscase.job.approve;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.admin.api.dto.UserSimpleInfoDto;
import com.ruicar.afs.cloud.admin.api.feign.AfsUserFeign;
import com.ruicar.afs.cloud.afscase.approvetask.condition.WorkTaskPoolCondition;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolService;
import com.ruicar.afs.cloud.afscase.common.utils.Const;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseBaseInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.job.approve.service.ApproveJobService;
import com.ruicar.afs.cloud.afscase.message.entity.CaseNoticeInfo;
import com.ruicar.afs.cloud.afscase.message.service.CaseNoticeInfoService;
import com.ruicar.afs.cloud.afscase.paramconfmanagement.entity.CaseConfParam;
import com.ruicar.afs.cloud.afscase.paramconfmanagement.service.CaseConfParamService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.job.core.biz.model.ReturnT;
import com.ruicar.afs.cloud.common.job.core.handler.annotation.AfsJob;
import com.ruicar.afs.cloud.common.job.core.handler.annotation.AfsJobHandler;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * <p>Description:</p>
 * 审批定时任务：<br/>
 *      1、自动撤销案件
 *      2、每单时效监测
 *      3、总时效监测
 *      4、单数差值监测
 *      5、离岗-案件监测
 *      6、无操作监测
 * @author maxueyu
 * */
@AfsJob
@AllArgsConstructor
@Slf4j
@Component
public class ApproveJob {

    private final CaseBaseInfoService caseBaseInfoService;
    private final WorkTaskPoolService workTaskPoolService;
    private final AfsUserFeign afsUserFeign;
    private final CaseNoticeInfoService caseNoticeInfoService;
    private final CaseConfParamService caseConfParamService;
    private final ApproveJobService approveJobService;
    /**
     * 自动撤销案件
     */
    @AfsJobHandler(value = "autoCancelFlow")
    public ReturnT<String> autoCancelFlow(String param){
        log.info("启动定时任务【自动撤销案件】");
        CaseConfParam approveTimeoutDaysConfParam=caseConfParamService.getOne(Wrappers.<CaseConfParam>query().lambda()
                .eq(CaseConfParam::getParamType, Const.APPROVE_TIMEOUT_DAYS));
        if (ObjectUtil.isNull(approveTimeoutDaysConfParam)){
            log.error("未配置审批超时天数参数！");
            throw new RuntimeException("未配置审批超时天数参数！");
        }
        int days = Integer.valueOf(approveTimeoutDaysConfParam.getParamValue());
        List<CaseBaseInfo> caseBaseInfoList = caseBaseInfoService.list(Wrappers.<CaseBaseInfo>query().lambda()
                .isNull(CaseBaseInfo::getPassLastDate)
                .le(CaseBaseInfo::getPassFirstDate, DateUtil.offsetDay(new Date(),-days))
                .ne(CaseBaseInfo::getBusinessStateIn, AfsEnumUtil.key(BusinessStateInEnum.REPEAL))
                .ne(CaseBaseInfo::getBusinessStateIn, AfsEnumUtil.key(BusinessStateInEnum.APPROVED))
                .ne(CaseBaseInfo::getBusinessStateIn, AfsEnumUtil.key(BusinessStateInEnum.REJECT))
                .ne(CaseBaseInfo::getBusinessStateIn, AfsEnumUtil.key(BusinessStateInEnum.CONDITIONAL_APPROVE)));
        if (caseBaseInfoList.size()!=0)
            log.info("检测到{}单审批超时（{}天）的案件",caseBaseInfoList.size(),days);
        List<String> cancelFailList= new ArrayList<>();
        for (int i = 0; i < caseBaseInfoList.size(); i++) {
            try{
                approveJobService.processAutoCancelFlow(caseBaseInfoList.get(i));
            }catch (Exception e){
                e.printStackTrace();
                cancelFailList.add(caseBaseInfoList.get(i).getApplyNo());
            }
        }
        if(CollectionUtil.isNotEmpty(cancelFailList)){
            throw new RuntimeException("申请编号"+StringUtils.join(cancelFailList,"、")+"撤销失败");
        }
        log.info("定时任务【自动撤销案件】执行成功");
        return ReturnT.SUCCESS;
    }

    /**
     * 无操作监测
     */
    @AfsJobHandler(value = "noOperateMonitor")
    public ReturnT<String> noOperateMonitor(String param){
        log.info("启动定时任务【无操作监测】");
        WorkTaskPoolCondition workTaskPoolCondition= new WorkTaskPoolCondition();
        //审批流程类型查询条件
        List processTypeList = new ArrayList();
        //常规审批
        processTypeList.add(ProcessTypeEnum.GENERA_APPROVE.getCode());
        //资产变更
        processTypeList.add(ProcessTypeEnum.CHANGE_ASSETS.getCode());
        //复议申请
        processTypeList.add(ProcessTypeEnum.RECONSIDER_APPLY.getCode());
        //正式复议
        processTypeList.add(ProcessTypeEnum.FORMAL_REVIEW.getCode());
        //车辆库存超期
        processTypeList.add(ProcessTypeEnum.INVENTORIES_ARE.getCode());
        //二次欺诈调查
        processTypeList.add(ProcessTypeEnum.SECONDARY_FRAUD.getCode());
        workTaskPoolCondition.setProcessTypeList(processTypeList);
        //指定审批状态查询条件
        List businessStateInList = new ArrayList();
        //待审核
        businessStateInList.add(AfsEnumUtil.key(BusinessStateInEnum.WAIT_CHECK));
        //建议核准
        businessStateInList.add(AfsEnumUtil.key(BusinessStateInEnum.ADVICE_APPROVED));
        //建议拒绝
        businessStateInList.add(AfsEnumUtil.key(BusinessStateInEnum.ADVICE_REJECT));
        //建议附条件核准
        businessStateInList.add(AfsEnumUtil.key(BusinessStateInEnum.ADVICE_CONDITIONAL));
        //修订-回复
        businessStateInList.add(AfsEnumUtil.key(BusinessStateInEnum.REVISE_REPLY));
        workTaskPoolCondition.setBusinessStateInList(businessStateInList);
        CaseConfParam caseNoOperateTimeConfParam=caseConfParamService.getOne(Wrappers.<CaseConfParam>query().lambda()
                .eq(CaseConfParam::getParamType, Const.NO_OPERATE_TIME));
        if (ObjectUtil.isNull(caseNoOperateTimeConfParam)){
            log.error("未配置无操作时长参数！");
            throw new RuntimeException("未配置无操作时长参数！");
        }
        workTaskPoolCondition.setNoOperateTime(caseNoOperateTimeConfParam.getParamValue());
        workTaskPoolCondition.setIsOpen(WhetherEnum.NO.getCode());
        //筛选待审批人员审批的案件
        List<String> noOperateApproveTaskList = workTaskPoolService.queryNoOperateApproveTaskList(workTaskPoolCondition);
        List<CaseNoticeInfo> noticeInfoList=new ArrayList<>();
        if(noOperateApproveTaskList.size()>0){
            CaseNoticeInfo caseNoticeInfo= new CaseNoticeInfo();
            StringBuffer sbf=new StringBuffer();
            caseNoticeInfo.setNoticeType(AfsEnumUtil.key(SysNoticeTypeEnum.JOB));
            caseNoticeInfo.setNotice(sbf.append("审批人员：").append(StringUtils.join(noOperateApproveTaskList,"、"))
                    .append("的队列案件持续无变动，请识别").toString());
            caseNoticeInfo.setSendBy("system");
            noticeInfoList.add(caseNoticeInfo);
        }
        //获取支持岗所有角色配置
        List<CaseConfParam> caseSupportRoleConfParamList=caseConfParamService.list(Wrappers.<CaseConfParam>query().lambda()
                .eq(CaseConfParam::getParamType, Const.SUPPORT_ROLE_ID));
        if (ObjectUtil.isNull(caseSupportRoleConfParamList)){
            log.error("未配置无操作时长参数【支持岗角色编号】！");
            throw new RuntimeException("未配置无操作时长参数【支持岗角色编号】");
        }
        if(noticeInfoList.size()!=0){
            //将过期的消息通知标记为已读
            caseNoticeInfoService.updateOutdatedNoticeRead(SysNoticeTypeEnum.JOB, ReadEnum.READ);
            caseSupportRoleConfParamList.forEach(caseSupportRoleConfParam -> {
                HashSet<UserSimpleInfoDto> userList = new HashSet<>();
                String[] supperRoles=caseSupportRoleConfParam.getParamValue().split(",");
                for (int i = 0; i < supperRoles.length; i++) {
                    List<UserSimpleInfoDto> userSimpleInfoList = afsUserFeign.getSimpleUserListByRoleCode(supperRoles[i]).getData();
                    if(CollectionUtil.isNotEmpty(userSimpleInfoList)){
                        userList.addAll(userSimpleInfoList);
                    }
                }
                //新增消息通知,设置未读状态
                caseNoticeInfoService.saveOrUpdateNoticeInfoBatch(noticeInfoList,userList,ReadEnum.UNREAD);
            });
        }
        log.info("定时任务【无操作监测】执行成功");
        return ReturnT.SUCCESS;
    }
}
